package drds.plus.executor.function.scalar.datatime;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.function.FunctionException;
import drds.plus.executor.function.scalar.ScalarFunction;
import drds.plus.executor.utils.Utils;
import drds.plus.sql_process.type.Type;
import drds.plus.sql_process.utils.OptimizerUtils;

import java.text.ParseException;
import java.util.Calendar;

/**
 * Adds N months to period P (in the format YYMM or YYYYMM). Returns a value in
 * the format YYYYMM. Note that the period argument P is not a date value.
 *
 * <pre>
 * mysql> SELECT PERIOD_ADD(200801,2);
 *         -> 200803
 * </pre>
 *
 * @author jianghang 2014-4-17 上午10:10:23
 * @since 5.0.7
 */
public class PeroidAdd extends ScalarFunction {

    public static final String[] DATE_FORMATS = new String[]{"yyyyMM", "yyMM", "yyyy-MM", "yy-MM"};

    public Object compute(ExecuteContext executeContext, Object[] args) {
        for (Object arg : args) {
            if (Utils.isNull(arg)) {
                return null;
            }
        }

        String value = Type.StringType.convert(args[0]);
        Integer peroid = Type.IntegerType.convert(args[1]);

        try {
            java.util.Date date = OptimizerUtils.parseDate(value, DATE_FORMATS);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.add(Calendar.MONTH, peroid);

            return cal.get(Calendar.YEAR) * 100 + cal.get(Calendar.MONTH) + 1;
        } catch (ParseException e) {
            throw new FunctionException(e);
        }

    }

    public Type getReturnType() {
        return Type.IntegerType;
    }

    public String[] getFunctionNames() {
        return new String[]{"PERIOD_ADD"};
    }
}
